package cn.bupt.osc.utils  
{  
	import flash.utils.Dictionary;  
	public class Hashtable  
	{  
		private var keys:Dictionary;  
		private var items:Dictionary;  
		private var hashSize:int;  
		
		/** 
		 * Initializes a new Hashtable instance. 
		 * 
		 * @param size The initial size of the Hashtable. 
		 */  
		public function Hashtable(size:int = 100)  
		{  
			keys = new Dictionary();  
			items = new Dictionary(true);  
			hashSize = 0;  
		}  
		/** 
		 * Add a key/data couple into the table. 
		 * 
		 * @param key The key. 
		 * @param obj The data associated with the key. 
		 * 注意Hashtable维持key添加多次需要remove多次 
		 */  
		public function add(key:*, item:*):Boolean  
		{  
			if (key == null)  
			{  
				return false;  
			}  
			if (item == null)  
			{  
				return false;  
			}  
			if (keys[key])  
			{  
				return false;  
			}  
			hashSize++;  
			
			keys[key] = item;  
			items[item] = key;  
			return true;  
		}  
		/** 
		 * Finds the value that is associated with the given key. 
		 * 
		 * @param  key The key mapping a value. 
		 * @return The data associated with the key or null if no matching 
		 *         entry was found. 
		 */  
		public function find(key:*):*  
		{  
			return keys[key];  
		}  
		/** 
		 * Removes a value based on a given key. 
		 * 
		 * @param  key The entry's key. 
		 * @return The data associated with the key or null if no matching 
		 *         entry was found. 
		 */  
		public function remove(key:*):*  
		{  
			var item:* = keys[key];  
			if (item)  
			{  
				delete keys[key];  
				delete items[item];  
				--hashSize;  
				return item;  
			}  
			return null;  
		}  
		/** 
		 * Checks if a mapping exists for the given key. 
		 * 
		 * @return True if key exists, otherwise false. 
		 */  
		public function containsKey(key:*):Boolean  
		{  
			return keys[key] != undefined;  
		}  
		/** 
		 * Writes all keys into an array. 
		 * 
		 * @return An array containing all keys. 
		 */  
		public function getKeySet():Array  
		{  
			var a:Array = new Array(hashSize), i:int;  
			for(var key:* in keys)  
			{  
				a[i++] = key;  
			}  
			return a;  
		}  
		/** 
		 * @inheritDoc 
		 */  
		public function contains(obj:*):Boolean  
		{  
			return items[obj] != undefined;  
		}  
		/** 
		 * @inheritDoc 
		 */  
		public function clear():void  
		{  
			keys = new Dictionary();  
			items = new Dictionary();  
			hashSize = 0;  
		}  
		
		/** 
		 * @inheritDoc 
		 */  
		public function get size():int  
		{  
			return hashSize;  
		}  
		/** 
		 * @inheritDoc 
		 */  
		public function isEmpty():Boolean  
		{  
			return hashSize == 0;  
		}  
		/** 
		 * @inheritDoc 
		 */  
		public function toArray():Array  
		{  
			var a:Array = new Array(hashSize), i:int;  
			for(var item:* in items)  
			{  
				a[i++] = item;  
			}  
			return a;  
		}  
		/** 
		 * Prints out a string representing the current object. 
		 * 
		 * @return A string representing the current object. 
		 */  
		public function toString():String  
		{  
			return "[Hashtable, size=" + size + "]";  
		}  
		
		/** 
		 * 克隆Hashtable 
		 */    
		public function clone():Hashtable{  
			var result : Hashtable = new Hashtable();  
			for(var key:* in keys)  
			{  
				result.add(key,keys[key]);  
			}  
			return result;  
		}  
		
		
		public function removeItem(item:Object):*{  
			var key:* = items[item];  
			if(key){  
				return remove(key);  
			}  
			return null;  
		}  
	}  
}  
